package net.jgrm.order.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * PostgreSQL pgcrypto加密工具类
 * 封装数据库原生加密功能，支持确定性加密哈希生成
 */
@Component
public class AESEncryptionUtil {

    /**
     * 加密密钥（生产环境中应该从配置文件或环境变量读取）
     */
    @Value("${order.encryption.key:MySecretKey12345}")
    private String secretKey;

    /**
     * 生成确定性加密哈希（用于数据库索引和查询）
     * 使用HMAC-SHA256生成确定性哈希值
     *
     * @param plainText 明文
     * @return 确定性哈希值（用于数据库索引）
     */
    public String generateDeterministicHash(String plainText) {
        try {
            // 使用秘钥和明文生成确定性哈希
            String keyedText = secretKey + plainText + secretKey;
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = digest.digest(keyedText.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hashBytes);
        } catch (Exception e) {
            throw new RuntimeException("生成确定性哈希失败", e);
        }
    }

    /**
     * 字节数组转十六进制字符串
     */
    private String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    /**
     * AES加密方法
     * 使用CBC模式和PKCS5Padding填充，自动生成随机IV并与密文一起返回
     *
     * @param plainText 待加密明文
     * @return 加密后的字符串（Base64编码，格式：IV(16字节)+密文）
     */
    public String encrypt(String plainText) {
        try {
            // 生成16字节随机IV
            byte[] iv = new byte[16];
            SecureRandom random = new SecureRandom();
            random.nextBytes(iv);
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            // 处理密钥（使用SHA-256哈希并截取前16字节作为128位密钥）
            SecretKeySpec keySpec = getAesKeySpec();

            // 初始化加密器
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

            // 执行加密
            byte[] encryptedData = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

            // 组合IV和密文（IV在前16字节）
            byte[] result = new byte[iv.length + encryptedData.length];
            System.arraycopy(iv, 0, result, 0, iv.length);
            System.arraycopy(encryptedData, 0, result, iv.length, encryptedData.length);

            // Base64编码便于存储传输
            return Base64.getEncoder().encodeToString(result);
        } catch (Exception e) {
            throw new RuntimeException("AES加密失败", e);
        }
    }

    /**
     * AES解密方法
     * 从加密字符串中提取IV并解密
     *
     * @param encryptedText 加密后的字符串（Base64编码）
     * @return 解密后的明文
     */
    public String decrypt(String encryptedText) {
        try {
            // Base64解码
            byte[] encryptedData = Base64.getDecoder().decode(encryptedText);

            // 提取IV（前16字节）
            byte[] iv = new byte[16];
            System.arraycopy(encryptedData, 0, iv, 0, iv.length);
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            // 提取密文（IV之后的字节）
            byte[] cipherText = new byte[encryptedData.length - iv.length];
            System.arraycopy(encryptedData, iv.length, cipherText, 0, cipherText.length);

            // 处理密钥（与加密时保持一致）
            SecretKeySpec keySpec = getAesKeySpec();

            // 初始化解密器
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            // 执行解密
            byte[] decryptedData = cipher.doFinal(cipherText);
            return new String(decryptedData, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("AES解密失败", e);
        }
    }

    /**
     * 处理密钥生成AES密钥规范
     * 使用SHA-256哈希原始密钥并截取前16字节（128位）
     */
    private SecretKeySpec getAesKeySpec() throws Exception {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] keyBytes = digest.digest(secretKey.getBytes(StandardCharsets.UTF_8));
        // 截取前16字节作为128位密钥（AES-128）
        byte[] aesKey = new byte[16];
        System.arraycopy(keyBytes, 0, aesKey, 0, aesKey.length);
        return new SecretKeySpec(aesKey, "AES");
    }


    public static void main(String[] args) {

        AESEncryptionUtil aes = new AESEncryptionUtil();
        aes.secretKey = "MySecretKey12345";
        String plainText = "科技园南区深圳湾科技生态园10栋A座";
        String encryptedText = aes.encrypt(plainText);
        System.out.println("Encrypted Text: " + encryptedText);
        String decryptedText = aes.decrypt(encryptedText);
        System.out.println("Decrypted Text: " + decryptedText);
        System.out.println("Deterministic Hash: " + aes.generateDeterministicHash(plainText));

    }

}